# app.py
import json
from datetime import datetime

from flask import Flask, jsonify, request

from db.StudentDB import StudentDB
from utils.AesUtils import AesUtils
from utils.ApiClient import ApiClient
from utils.ResponseUtils import ResponseUtils
from django.db import transaction

app = Flask(__name__)

code200 = 200
code1 = 1


@app.route('/api/data')
def get_data():
    return jsonify({
        'data': ['Python', 'Vue.js', 'Element-UI', 'Flask']
    })


@app.route('/api/students/list', methods=['GET'])
def get_list():
    # 1. 获取并验证参数
    schoolName = request.args.get('schoolName', type=str)
    studentCode = request.args.get('studentCode', type=str)
    idCard = request.args.get('idCard', type=str)
    itemName = request.args.get('itemName', type=str)
    gender = request.args.get('gender', type=str)
    groupNo = request.args.get('groupNo', type=str)
    status = request.args.get('status', type=str)
    page_num = request.args.get('pageNum', default=1, type=int)
    page_size = request.args.get('pageSize', default=50, type=int)
    if page_num < 1 or page_size < 1:
        raise ValueError("分页参数必须大于0")
    studentsDB = StudentDB()
    list = studentsDB.search_students_with_pagination(
        {"schoolName": schoolName, "studentCode": studentCode, "idCard": idCard, "itemName": itemName, "gender": gender,
         "groupNo": groupNo, "status": status}, page_num, page_size)
    # 使用示例
    return ResponseUtils.build_response(code200, "success", "数据查询成功", list[0], list[1])


@app.route('/api/students/delete_all', methods=['DELETE'])
def delete_all():
    studentsDB = StudentDB()
    bol = studentsDB.delete_all_student()
    if (bol):
        return ResponseUtils.build_response(code200, "success", "清空成功")
    else:
        return ResponseUtils.build_response(code200, "success", "清空失败")


@transaction.atomic
@app.route('/api/students/get/list', methods=['GET'])
def get_api_list():
    # 清空考生数据
    delete_all()

    # 调用接口获取考生数据
    # 创建 API 客户端实例
    api = ApiClient(config_file="../config/apiconfig.ini")

    # GET 请求示例
    print("=== GET 请求示例 获取访问令牌 ===")
    api._authenticate()
    print(f"siteCode：" + api.siteCode)
    print(f"siteName：" + api.siteName)
    print(f"type：" + api.type)
    print(f"encryptKey：" + api.encryptKey)
    print(f"token：" + api.token)
    print(f"typeValue：" + api.typeValue)

    studentCond = 1
    while studentCond > 0:
        # POST 请求示例
        print("\n=== POST 请求示例 考生信息下载 ===")
        response = api.post(
            api.base_url,
            api.student_url,
            json_data={
                "data": {
                    "itemCode": "",
                    "pageNo": studentCond
                },
                "msEquipment": "",
                "requestTime": 0,
                "encrypt": "0",
                "version": "1.0.0",
                "lastUpdateTime": "",
            },
            headers={
                "Authorization": "Bearer " + api.token
            }
        )
        print(response)
        print(response.get("data"))
        if 1 == response.get("code"):
            error_msg = f"考生信息查询失败: {response.code} - {response.msg}"
            api.logger.error(error_msg)
            return ResponseUtils.build_response(-1, "erroe", "考生信息查询失败:" + error_msg)
            # raise ApiRequestError(error_msg, response=response)
        studentData = response.get("data")
        # 创建 AES 加密器
        encryptKey = api.encryptKey.encode('utf-8')
        aes = AesUtils(encryptKey)
        print("考生加密信息:", studentData)
        # 解密（输入 HEX）
        decrypted_text = aes.decrypt(studentData)
        data = json.loads(decrypted_text)
        if "studentList" in data and isinstance(data["studentList"], list):
            studentCond = studentCond + 1
            # 批量插入
            process_student_data(decrypted_text)
        else:
            studentCond = 0
            print("未找到有效的studentList，流程结束")
        print("解密结果:", data)
    # studentsDB = StudentDB()
    # students = studentsDB.search_students({}, 50)
    # 使用示例
    return ResponseUtils.build_response(code200, "success", "同步成功")


def process_student_data(json_data):
    """处理学生数据的主函数"""
    try:
        # 1. 解析JSON字符串
        data = json.loads(json_data)
        print("解密结果:", data)

        # 2. 检查studentList是否存在且非空
        if "studentList" in data and isinstance(data["studentList"], list):
            print("检测到studentList，开始批量插入...")
            studentsDB = StudentDB()
            studentsDB.insert_students_batch(data["studentList"])
            print("插入完成")
        else:
            print("未找到有效的studentList，流程结束")

    except json.JSONDecodeError:
        print("错误：无效的JSON格式")
    except Exception as e:
        print(f"处理过程中发生错误：{str(e)}")


# 获取云平台未同步的考生列表信息
@app.route('/api/exam/cloud/student/list', methods=['GET'])
def get_exam_cloud_student_list():
    print("云平台接口调用开始")
    api = ApiClient(config_file="../config/apiconfig.ini")
    try:
        zkh = request.args.get('zkh', type=str)
        jdh = request.args.get('jdh', type=str)
        zxmc = request.args.get('zxmc', type=str)
        sfzh = request.args.get('sfzh', type=str)
        xcxm = request.args.get('xcxm', type=str)
        pageNum = request.args.get('pageNum', default=1, type=int)
        pageSize = request.args.get('pageSize', default=50, type=int)
        headers = {
            "Content-Type": "application/x-www-form-urlencoded"
        }
        params = {
            "zkh": zkh,
            "jdh": jdh,
            "zxmc": zxmc,
            "sfzh": sfzh,
            "xcxm": xcxm,
            "pageNum": pageNum,
            "pageSize": pageSize
        }
        response = api.post(
            api.cloud_url,
            api.fpl_student_url,
            json_data=params
        )
        print(response)
        print(response.get("code"))
        print(response.get("data"))
        if (code200 == response.get("code")):
            data = response.get("data")
            print(data)
            rows = data.get("rows")
            print(rows)
            total = data.get("total")
            print(total)
            return response
        else:
            return ResponseUtils.build_response(code1, "error", response.get("msg"))
    except Exception as e:
        print(f"云平台接口调用过程中发生错误: {str(e)}")
        raise


# 同步平台成绩至本地
@app.route('/api/sync/cloud/result/local', methods=['POST'])
def sync_cloud_result_local():
    print("云平台接口调用开始")
    api = ApiClient(config_file="../config/apiconfig.ini")
    try:
        # zkh = request.args.get('zkh', type=str)
        # jdh = request.args.get('jdh', type=str)
        # zxmc = request.args.get('zxmc', type=str)
        # sfzh = request.args.get('sfzh', type=str)
        # xcxm = request.args.get('xcxm', type=str)
        # pageNum = request.args.get('pageNum', default=1, type=int)
        # pageSize = request.args.get('pageSize', default=50, type=int)

        # 获取 JSON 请求体
        data = request.get_json()
        if not data:
            return ResponseUtils.build_response(code1, "error", "请求体必须为JSON格式")

        # 从 JSON 中提取参数
        zkh = data.get('zkh')
        zkhs = data.get('zkhs')
        jdh = data.get('jdh')
        zxmc = data.get('zxmc')
        sfzh = data.get('sfzh')
        xcxm = data.get('xcxm')
        pageNum = data.get('pageNum', 1)
        pageSize = data.get('pageSize', 50)

        headers = {
            "Content-Type": "application/x-www-form-urlencoded"
        }

        dataJson = {
            "zkh": zkh,
            "zkhs": zkhs,
            "jdh": jdh,
            "zxmc": zxmc,
            "sfzh": sfzh,
            "xcxm": xcxm,
            "pageNum": pageNum,
            "pageSize": pageSize
        }
        response = api.post(
            api.cloud_url,
            api.fpl_student_url,
            json_data=dataJson
        )
        print(response)
        print(response.get("code"))
        print(response.get("data"))
        if (code200 == response.get("code")):
            data = response.get("data")
            print(data)
            rows = data.get("rows")
            print(rows)
            total = data.get("total")
            print(total)
            localZkh = []
            fplUpLogs = []
            for row in rows:
                zkh = row['zkh']
                examResult = row['examResult']
                result_str = f"{examResult:.0f}"
                mtEquipment = row['mtEquipment']
                resultId = row['resultId']
                gmtStarted = row['gmtStarted']
                studentsDB = StudentDB()
                student1 = studentsDB.get_student_by_zkh_item(zkh, xcxm)
                if student1 is not None:
                    try:
                        studentsDB.update_student(student1['id'],
                                                  {"result": result_str, "mtEquipment": mtEquipment, "status": 1,
                                                   "resultId": resultId, "gmtStarted": gmtStarted})
                        fplUpLog = {"zkh": zkh, "item": xcxm, "result": result_str}
                        fplUpLogs.append(fplUpLog)
                    except Exception as e:
                        print(f"无法添加result属性: {e}")
                        print(f"student1类型: {type(student1)}")
                    print(student1.get("zkh"))
                else:
                    localZkh.append(zkh)
                    total = total - 1
                print(student1)
            print(fplUpLogs)
            # 修改完成后调用云平台上传提交次数接口
            # response1 = api.post(
            #     api.cloud_url,
            #     api.fpl_student_up_count,
            #     json_data=fplUpLogs
            # )
            # print(response1)
            # print(response1.get("code"))
            warnStr = ""
            if (len(localZkh)):
                warnStr = "准考证号为" + str(localZkh) + "不在本地"
            if warnStr == '':
                return ResponseUtils.build_response(code200, "success",
                                                    "同步成功，同步数量为：" + str(total) + ";" + warnStr)
            else:
                return ResponseUtils.build_response(code1, "warning",
                                                    "同步成功，同步数量为：" + str(total) + ";" + warnStr)
        else:
            return ResponseUtils.build_response(code1, "error", response.get("msg"))
    except Exception as e:
        print(f"云平台接口调用过程中发生错误: {str(e)}")
        raise


def get_current_timestamp():
    """获取当前时间戳（毫秒级）"""
    return int(datetime.now().timestamp() * 1000)


# 上传本地待上传的数据到第三方
@transaction.atomic
@app.route('/api/sync/local/result/third', methods=['GET'])
def sync_local_result_third():
    api = ApiClient(config_file="../config/apiconfig.ini")
    studentsDB = StudentDB()
    # 获取状态为待上传的考生数据
    students = studentsDB.search_students({"status": "1"})
    api._authenticate()
    # 检查数据有效性
    if students is None:
        print("错误: 查询返回了 None")
        print("没有找到符合条件的学生或查询结果为空")
        return ResponseUtils.build_response(code1, "warning", "没有找到符合条件的学生或查询结果为空；")
    elif not students:  # 空列表/字典/集合等
        print("警告: 查询返回了空结果")
        print("没有找到符合条件的学生或查询结果为空")
        return ResponseUtils.build_response(code1, "warning", "没有找到符合条件的学生或查询结果为空；")
    else:
        total = 0
        # 请求时间，时间戳
        requestTime = get_current_timestamp()
        # 错误码 ：0表示成功，其它均为失败
        msEquipment = 0
        # 加密标识0-不加密，1-加密；只对data加密
        encrypt = 0
        # 版本号
        version = "1.0.0"
        jsonData = {
            "msEquipment": msEquipment,
            "encrypt": encrypt,
            "requestTime": requestTime,
            "version": version,
            "token": api.token,
            "data": []
        }
        # 初始化 data_list（JSON 数组）
        data_list = []
        fplUpLogs = []
        # 尝试遍历
        print("\n开始遍历学生数据:")
        for student in students:
            try:
                print("上传开始")
                # 发送成绩给第三方
                # 体测或考试id
                id = student["id"]
                # 体测或考试id
                testId = student["testId"]
                # 学校代码(考点代码)
                siteCode = student["siteCode"]
                # 日程编号-考试使用
                scheduleNo = student["scheduleNo"]
                # 准考证号
                studentCode = student["studentCode"]
                # 项目代码
                itemCode = student["itemCode"]
                # 项目名称
                itemName = student["itemName"]
                # 性别
                gender = student["gender"]
                # 组号-考试使用
                groupNo = student["groupNo"]
                # 组内序号-考试使用
                trackNo = student["trackNo"]
                # 测试轮次顺序号
                # 比如规定测试次数为3；第⼀次测试序号：1，第⼆次测试序号2，第三次测试序号3；
                roundNo = 1
                # 成绩状态：1:正常 2:犯规 3:中退 4:弃权 5:测试-考试使用
                resultStatus = 1
                # 考试状态（0.正常，2.补考）-考试使用
                studentItemStatus = 0
                # 测试用户名
                userInfo = "xuetong"
                # 视频设备信息唯⼀编码，多个用英文逗号分隔
                mtEquipment = student["mtEquipment"]
                # 是否重测：0 否 1 是
                isRetest = "0"
                # 临时组号
                tempGroupNo = student["groupNo"]
                # 临时道号
                tempTrackNo = student["trackNo"]
                # 组别名称
                sortName = student["sortName"]
                # 考试类型: 0.正常 1.缓考
                examType = "0"
                # 成绩
                result = student["result"]
                # 考试记录ID
                resultId = student["resultId"]
                # 考试开始时间
                gmtStarted = student["gmtStarted"]
                if gmtStarted:
                    # 转换为 datetime 对象
                    dt = datetime.strptime(gmtStarted, "%Y-%m-%d %H:%M:%S")
                    # 转换为时间戳（秒级）
                    gmtStartedTamp = dt.timestamp()
                else:
                    gmtStartedTamp = requestTime
                data = {
                    "testId": testId,
                    "siteCode": siteCode,
                    "scheduleNo": scheduleNo,
                    "studentCode": studentCode,
                    "itemCode": itemCode,
                    "gender": gender,
                    "testTime": gmtStartedTamp,
                    "groupNo": groupNo,
                    "trackNo": trackNo,
                    "roundNo": roundNo,
                    "resultStatus": resultStatus,
                    "studentItemStatus": studentItemStatus,
                    "userInfo": userInfo,
                    "mtEquipment": mtEquipment,
                    "isRetest": isRetest,
                    "tempGroupNo": tempGroupNo,
                    "tempTrackNo": tempTrackNo,
                    "result": str(result),
                    "examType": examType,
                    "groupType": 2,
                    "sortName": sortName
                }
                data_list.append(data)
                fplUpLog = {"id": id, "zkh": studentCode, "item": itemName, "result": str(result),
                            "resultId": str(resultId)}
                fplUpLogs.append(fplUpLog)
            except Exception as e:
                print(f"组装上传成绩json发生错误: {str(e)}")
                raise
        jsonData["data"] = data_list
        print("上传成绩至第三方开始")
        print("请求参数如下：")
        print(str(jsonData))
        response = api.post(
            api.base_url,
            api.upload_result_info,
            json_data=jsonData,
            headers={
                "Authorization": "Bearer " + api.token}
        )
        print(str(response))
        print(str(response.get("data")))
        if 1 == response.get("code"):
            print("考生成绩上传第三方失败，原因如下：")
            print(str(response))
            return ResponseUtils.build_response(code1, "error", "考生成绩上传第三方失败，原因如下：" + str(response.msg))
        dataStr = None
        if response.get("data") is not None:
            # 创建 AES 加密器
            encryptKey = api.encryptKey.encode('utf-8')
            aes = AesUtils(encryptKey)
            dataStr = aes.decrypt(response.get("data"))
            print("dataStr：" + dataStr)
            # print("考生成绩上传第三方失败，原因如下：")
            # print(str(response))
            # return ResponseUtils.build_response(code1, "error", "考生成绩上传第三方失败，原因如下：" + str(response.msg))
        if '[]' == dataStr or response.get("data") is None or dataStr is None:
            print("调用云平台上传提交次数开始")
            print("请求参数如下：")
            print(str(fplUpLogs))
            # 修改完成后调用云平台上传提交次数接口
            response1 = api.post(
                api.cloud_url,
                api.fpl_student_up_count,
                json_data=fplUpLogs
            )
            print(response1)
            print(response1.get("code"))
            if 200 == response1.get("code"):
                for fplUpLog in fplUpLogs:
                    studentsDB.update_student(fplUpLog["id"], {"status": 2})
                    total = total + 1
                return ResponseUtils.build_response(code200, "success", "处理完成，同步总数量：" + str(total))
            else:
                print("调用云平台上传提交次数失败，原因如下：")
                print(str(response1))
                return ResponseUtils.build_response(code1, "error",
                                                    "调用云平台上传提交次数失败，原因如下：" + str(response1.msg))


# 获取组内考生成绩信息
@app.route('/api/print/result', methods=['POST'])
def print_result():
    try:
        # 获取 JSON 请求体
        data = request.get_json()
        if not data:
            return ResponseUtils.build_response(code1, "error", "请求体必须为JSON格式")
        # 从 JSON 中提取参数
        studentCodes = data.get('studentCodes')
        groupNo = data.get('groupNo')
        studentsDB = StudentDB()
        student = studentsDB.get_students_by_zkh_groupNo(groupNo)
        return ResponseUtils.build_response(code200, "success", "查询成功", student)
    except Exception as e:
        print(f"获取组内考生成绩信息中发生错误: {str(e)}")
        raise

